﻿/**
 * 用户列表视图类的构造方法。
 * @param hasBorder 有边框则为 true，否则为 false
 * @param hasText   是否显示文字
 * @param parent    父视图
 * @param width     宽度
 * @param height    高度
 * @param x, y      左上角坐标
 * @return 用户列表视图
 */
function UserListView(hasBorder, hasText, parent, width, height, x, y) {
    const listView = document.createElement("div")              // 列表视图
    var mItemCount = 0                                          // item 数量
    var mNextItemX = Const.USER_LIST_VIEW_MARGIN_H   // 下一个 item 的 X 坐标
    var mNextItemY = Const.USER_LIST_VIEW_MARGIN_V   // 下一个 item 的 Y 坐标
    const mHighLight = document.createElement("canvas")         // 选中 item 时显示的半透明高亮
    var mSelectedItem = null                                    // 选中的表项
    var mTime = 0                                               // 上一次单击表项的时间

    // 显示边框
    if (hasBorder) {
        listView.style.border = "1px solid gray"
    }

    // 隐藏水平滚动条
    listView.style.overflowX = "hidden"

    // 设置位置
    listView.style.position = "absolute"
    listView.style.left = x + "px"
    listView.style.top = y + "px"

    // 设置尺寸
    listView.style.width = width + "px"
    listView.style.height = height + "px"

    // 添加到父视图
    parent.appendChild(listView)

    // 创建高亮
    createHighLight()

    /**
     * 添加一个带图标的表项。
     * @param iconIndex 图标索引
     */
    listView.addItem_icon = function(iconIndex) {
        // 创建图标
        var iconFilePath = Const.ICON_FILE_PATH
        if (iconIndex < 10) {
            iconFilePath = iconFilePath.replace("%s", "0" + iconIndex)
        } else {
            iconFilePath = iconFilePath.replace("%s", iconIndex)
        }
        const icon = document.createElement("img")
        icon.style.position = "absolute"
        icon.style.left = mNextItemX + "px"
        icon.style.top = mNextItemY + "px"
        icon.style.width = Const.ICON_SIZE + "px"
        icon.style.height = Const.ICON_SIZE + "px"
        icon.src = iconFilePath
        icon.itemIndex = mItemCount
        listView.appendChild(icon)

        // 计算下一个图标的位置
        mNextItemX += Const.ICON_SIZE + Const.USER_LIST_VIEW_MARGIN_H

        // 如果超出显示区域，则换行
        if (mNextItemX + Const.ICON_SIZE > width) {
            mNextItemX = Const.USER_LIST_VIEW_MARGIN_H
            mNextItemY += Const.ICON_SIZE + Const.USER_LIST_VIEW_MARGIN_V
        }

        // item 总数加1
        mItemCount++
    }

    /**
     * 添加一个带图标和文字的表项。
     * @param iconIndex 图标索引
     * @param itemText  表项文字
     * @param colorful  彩色则为 true，灰色则为 false
     */
    listView.addItem_icon_text = function(iconIndex, itemText, colorful) {
        // 添加表项
        const item = document.createElement('div')
        item.style.position = 'absolute'
        item.style.left = '0px'
        item.style.top = (Const.ICON_SIZE + Const.USER_LIST_VIEW_MARGIN_V * 2) * mItemCount + 'px'
        item.style.width = width  + 'px'
        item.style.height = (Const.ICON_SIZE + Const.USER_LIST_VIEW_MARGIN_V * 2) + 'px'
        listView.appendChild(item)

        // 添加图标
        const icon = document.createElement('img')
        icon.style.position = 'absolute'
        icon.style.left = Const.USER_LIST_VIEW_MARGIN_H + 'px'
        icon.style.top = Const.USER_LIST_VIEW_MARGIN_V + 'px'
        var iconFilePath = colorful ? Const.ICON_FILE_PATH: Const.GRAY_ICON_FILE_PATH
        if (iconIndex < 10) {
            iconFilePath = iconFilePath.replace("%s", "0" + iconIndex)
        } else {
            iconFilePath = iconFilePath.replace("%s", iconIndex)
        }
        icon.src = iconFilePath
        icon.itemIndex = mItemCount
        item.appendChild(icon)

        // 添加文字标签
        const label = document.createElement('label')
        label.style.position = 'absolute'
        label.style.left = (Const.ICON_SIZE + Const.USER_LIST_VIEW_MARGIN_H * 2) + 'px'
        label.style.top = '0px'
        label.style.width = (width - Const.ICON_SIZE - Const.USER_LIST_VIEW_MARGIN_H) + 'px'
        label.style.height = item.style.height
        label.style.lineHeight = label.style.height
        label.style.fontSize = Const.REG_WINDOW_USER_LIST_TEXT_SIZE + 'px'
        label.innerHTML = itemText
        label.itemIndex = mItemCount
        item.appendChild(label)

        // 计算下一个图标的位置
        mNextItemY += Const.ICON_SIZE + Const.USER_LIST_VIEW_MARGIN_V * 2

        // item 总数加1
        mItemCount++
    }

    /**
     * 改变某个表项的图标颜色。
     * @param itemText  表项的文字
     * @param colorful  彩色则为 true，灰色则为 false
     */
    listView.changeItemColor = function(itemText, colorful) {
        // 查找表项
        for (var i = 1; i < listView.childElementCount; i++) {
            const label = listView.childNodes[i].childNodes[1]
            if (label.innerHTML == itemText) {
                // 找到了
                const icon = listView.childNodes[i].firstChild
                var iconFilePath = icon.src.split(".")
                if (colorful) {
                    icon.src = iconFilePath[0].replace(Const.GRAY_ICON_FILE_TAIL, "") + "." + iconFilePath[1]
                } else {
                    icon.src = iconFilePath[0] + Const.GRAY_ICON_FILE_TAIL + "." + iconFilePath[1]
                }
                break 
            }
        }
    }

    /**
     * 清除所有表项。
     */
    listView.clear = function() {
        for (var i = mItemCount; i > 0; i--) {
            listView.removeChild(listView.childNodes[i])
        }
        mItemCount = 0
        mHighLight.style.display = "none"
    }

    /**
     * 创建高亮。
     */
    function createHighLight() {
        // 计算高亮的尺寸
        if (hasText) {
            mHighLight.width = width
            mHighLight.height = Const.ICON_SIZE + Const.USER_LIST_VIEW_MARGIN_V * 2
        } else {
            mHighLight.width = Const.ICON_SIZE
            mHighLight.height = Const.ICON_SIZE
        }

        // 画半透明矩形
        const drawer = mHighLight.getContext("2d")
        drawer.fillStyle = "green"
        drawer.globalAlpha = 0.4
        drawer.fillRect(0, 0, mHighLight.width, mHighLight.height)

        // 设置高亮的属性
        mHighLight.style.position = "absolute"
        mHighLight.style.display = "none"   // 默认为隐藏

        // 添加高亮
        listView.appendChild(mHighLight)
    }

    /**
     * 获取选中的表项的索引。
     * @return 选中的表项的索引
     */
    listView.getSelectedItemIndex = function() {
        if (mSelectedItem == null) {
            return -1
        }
        return mSelectedItem.itemIndex
    }

    /**
     * 获取选中的表项。
     * @return 选中的表项
     */
    listView.getSelectedItem = function() {
        return mSelectedItem
    }

    /**
     * 获取选中的表项的文字。
     * @return 选中的表项的文字
     */
    listView.getSelectedItemText = function() {
        if (mSelectedItem == null) {
            return ""
        }
        return mSelectedItem.lastChild.innerHTML
    }

    /**
     * 表项单击事件的响应方法。
     * @param e 事件相关信息
     */
    listView.onclick = function(e) {
        // 如果是双击则返回
        const time = new Date().getTime()
        if (time - mTime <= 300) {
            return
        }
        mTime = time

        // 获取选中的表项
        var selectedItem = e.srcElement
        if (selectedItem == listView) {
            mHighLight.style.display = "none"
            mSelectedItem = null
            return
        }

        // 计算高亮的位置
        if (hasText) {
            if (selectedItem.localName == "img" || selectedItem.localName == "label") {
                selectedItem = selectedItem.parentElement
            } else if (selectedItem.localName != "div") {
                return
            }
            mHighLight.style.left = "1px"
            mHighLight.style.top = selectedItem.style.top
        } else {
            if (selectedItem.localName != "img") {
                return
            }
            mHighLight.style.left = selectedItem.style.left
            mHighLight.style.top = selectedItem.style.top
        }

        // 显示高亮
        mHighLight.style.display = "block"

        // 保存选中的表项的索引
        mSelectedItem = selectedItem
    }

    return listView
}
